package com.controller.sys.user;

import com.common.ErrorCodeEnum;
import com.common.anntation.Log;
import com.common.config.Config;
import com.common.emums.BusinessType;
import com.common.emums.DataStatus;
import com.common.emums.UserType;
import com.common.exception.BusinessException;
import com.common.utils.EntityConversionUtil;
import com.common.utils.Md5Utils;
import com.common.utils.StringUtils;
import com.common.utils.file.FileUploadUtils;
import com.core.springSecurity.service.PermissionService;
import com.github.pagehelper.PageInfo;
import com.model.base.PageResult;
import com.model.base.Result;
import com.model.domain.sys.GetUserListDO;
import com.model.dto.sys.userController.CreateUserDTO;
import com.model.dto.sys.userController.GetUserListDTO;
import com.model.dto.sys.userController.UpdateUserInfoListDTO;
import com.model.dto.sys.userController.UpdateUserStatusDTO;
import com.model.pojo.sys.SysUser;
import com.model.vo.sys.user.UserVO;
import com.service.sys.SysDeptService;
import com.service.sys.SysRoleService;
import com.service.sys.SysUserRoleService;
import com.service.sys.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 用户管理
 */

@Api(tags = {"用户管理模块"})
@Slf4j
@RestController
@RequestMapping("/v1")
public class UserController {

    @Resource
    SysUserService sysUserService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SysDeptService sysDeptService;

    @Resource
    SysUserRoleService sysUserRoleService;

    /**
     * @param createUserDTO 创建信息
     * @Author: zql
     * @Description: 创建用户
     * @Data: 15:59 2021/5/10
     */
    @ApiOperation(value = "创建用户")
    @Log(title = "创建用户", businessType = BusinessType.INSERT,  isSaveRequestData = true, isSaveResponseData = true)
    @PostMapping("/createUser")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> createUser(@RequestBody @Valid CreateUserDTO createUserDTO) {
        if (StringUtils.isNotNull(createUserDTO.getSysDeptId()) && !sysDeptService.has(createUserDTO.getSysDeptId())) {
            log.error("创建用户过程绑定了不存在的部门 部门id:{}", createUserDTO.getSysDeptId());
            throw new BusinessException(ErrorCodeEnum.DEPT_NOT_FOUND);
        }
//        if(StringUtils.isNotNull(createUserDTO.getSysRoleIds()) && createUserDTO.getSysRoleIds().stream().anyMatch(roleId->!sysRoleService.has(roleId))){
//            log.error("创建用户过程绑定了不存在的角色");
//            throw new BusinessException(ErrorCodeEnum.ROLE_NOT_FOUNT);
//        }
        if (sysUserService.hasName(createUserDTO.getName())) {
            log.error("登录用户名重复:{}", createUserDTO.getName());
            throw new BusinessException(ErrorCodeEnum.USER_NAME_EXISTS);
        }
        if (StringUtils.isNotEmpty(createUserDTO.getMobile()) && sysUserService.hasMobile(createUserDTO.getMobile())) {
            log.error("手机号重复:{}", createUserDTO.getMobile());
            throw new BusinessException(ErrorCodeEnum.USER_MOBILE_EXISTS);
        }
        if (StringUtils.isNotEmpty(createUserDTO.getEmail()) && sysUserService.hasEmail(createUserDTO.getEmail())) {
            log.error("邮箱重复:{}", createUserDTO.getEmail());
            throw new BusinessException(ErrorCodeEnum.USER_EMAIL_EXISTS);
        }
        SysUser sysUser = EntityConversionUtil.copy(createUserDTO,SysUser.class);
        //这里使用对暴露的密码转成MD532位并加密
        sysUser.setPassword(sysUserService.encode(Md5Utils.toUpperCase32(sysUser.getPassword())));
        sysUserService.create(sysUser);
        if (StringUtils.isNotNull(createUserDTO.getSysRoleIds())) {
            sysUserRoleService.bindingUser(sysUser.getSysUserId(), createUserDTO.getSysRoleIds());
        }
        return Result.suc();
    }

    /**
     * @param file 头像文件
     * @Author: zql
     * @Description: 更换用户头像
     * @Data: 15:16 2021/5/10
     */
    @ApiOperation(value = "更换用户头像")
    @Log(title = "更换用户头像", businessType = BusinessType.UPDATE,  isSaveResponseData = true)
    @PostMapping("/uploadAvatar")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> uploadAvatar(
            @ApiParam(name = "avatarfile", value = "头像图片", required = true)
            @RequestParam("avatarfile") MultipartFile file,
            @ApiParam(name = "sysUserId", value = "用户id", required = true)
            @RequestParam("sysUserId")
            Long sysUserId) {
        if(!sysUserService.has(sysUserId)){
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        if (!file.isEmpty()) {
            String avatar ;
            try {
                avatar = FileUploadUtils.upload(Config.getAvatarPath(), file);
            } catch (IOException e) {
                e.printStackTrace();
                return Result.fail(ErrorCodeEnum.UPLOAD_FILE);
            }
            //更新数据库用户头像
            SysUser sysUser=new SysUser();
            sysUser.setSysUserId(sysUserId);
            sysUser.setImagePath(avatar);
            sysUserService.update(sysUser);
            return Result.suc();
        }
        return Result.fail(ErrorCodeEnum.UPDATE_USER_IMAGE_FAILED);
    }

    /**
     * @param updateUserInfoListDTO 修改的用户信息
     * @Author: zql
     * @Description: 批量修改用户信息
     * @Data: 10:04 2021/5/11
     */
    @ApiOperation(value = "批量修改用户信息")
    @Log(title = "批量修改用户信息", businessType = BusinessType.UPDATE,  isSaveRequestData = true)
    @PostMapping("/updateUserInfoList")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> updateUserInfoList(@RequestBody @Valid UpdateUserInfoListDTO updateUserInfoListDTO) {
        List<SysUser> sysUserList = new ArrayList<>();
        Map<Long, Set<Long>> map = new HashMap<>();
        updateUserInfoListDTO.getUserInfoSet().forEach(userInfo -> {
            if (StringUtils.isNull(userInfo.getSysUserId()) || !sysUserService.has(userInfo.getSysUserId())) {
                throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
            }
            if (StringUtils.isNotNull(userInfo.getSysRoleIds()) && userInfo.getSysRoleIds().stream().anyMatch(roleId -> !sysRoleService.has(roleId))) {
                log.error("创建用户过程绑定了不存在的角色");
                throw new BusinessException(ErrorCodeEnum.ROLE_NOT_FOUNT);
            }
            if (StringUtils.isNotNull(userInfo.getSysDeptId()) && !sysDeptService.has(userInfo.getSysDeptId())) {
                log.error("创建用户过程绑定了不存在的部门 部门id:{}", userInfo.getSysDeptId());
                throw new BusinessException(ErrorCodeEnum.DEPT_NOT_FOUND);
            }
            SysUser sysUser = sysUserService.get(userInfo.getSysUserId());
            BeanUtils.copyProperties(userInfo, sysUser);
            if (StringUtils.isNotEmpty(userInfo.getPassword())) {
                sysUser.setPassword(sysUserService.encode(Md5Utils.toUpperCase32(userInfo.getPassword())));
            }
            sysUserService.verifyUserInfo(sysUser, true);
            sysUserList.add(sysUser);

            if (StringUtils.isNotNull(userInfo.getSysRoleIds())) {
                map.put(sysUser.getSysUserId(), userInfo.getSysRoleIds());
            }
        });
        if (sysUserList.size() > 0) {
            sysUserService.updateList(sysUserList);
        }
        for (Long sysUserId : map.keySet()) {
            sysUserRoleService.bindingUser(sysUserId, map.get(sysUserId));
        }
        return Result.suc();
    }

    @ApiOperation(value = "修改用户状态")
    @Log(title = "修改用户状态", businessType = BusinessType.DELETE,  isSaveRequestData = true)
    @PostMapping("/updateUserStatus")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> updateUserStatus(@RequestBody @Valid UpdateUserStatusDTO updateUserStatusDTO) {
        if (1 == updateUserStatusDTO.getSysUserId()) {
            throw new BusinessException(ErrorCodeEnum.ROOT_USER);
        }
        if (!sysUserService.has(updateUserStatusDTO.getSysUserId(), null)) {
            log.error("用户不存在 userId:{}", updateUserStatusDTO.getSysUserId());
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        SysUser sysUserDB = sysUserService.get(updateUserStatusDTO.getSysUserId());
        SysUser sysUser = new SysUser();

        if (DataStatus.OK.equals(updateUserStatusDTO.getIsDelete()) && !DataStatus.OK.equals(sysUserDB.getIsDelete())) {
            if (!sysDeptService.has(sysUserDB.getSysDeptId())) {
                //如果用户恢复的时候部门不存在，分配到1号部门
                sysUser.setSysDeptId(1L);
            }
            if (sysUserService.hasName(sysUserDB.getName())) {
                throw new BusinessException(ErrorCodeEnum.USER_NAME_EXISTS);
            }
            if (StringUtils.isNotEmpty(sysUserDB.getMobile()) && sysUserService.hasMobile(sysUserDB.getMobile())) {
                throw new BusinessException(ErrorCodeEnum.USER_MOBILE_EXISTS);
            }
            if (StringUtils.isNotEmpty(sysUserDB.getEmail()) && sysUserService.hasEmail(sysUserDB.getEmail())) {
                throw new BusinessException(ErrorCodeEnum.USER_EMAIL_EXISTS);
            }
        }
        sysUser.setSysUserId(updateUserStatusDTO.getSysUserId());
        sysUser.setIsDelete(updateUserStatusDTO.getIsDelete());
        sysUserService.update(sysUser);
        return Result.suc();
    }
    /**
     * @param getUserListDTO 查看条件
     * @Author: zql
     * @Description: 查看用户列表
     * @Data: 15:19 2021/5/10
     */
    @ApiOperation(value = "查看用户列表")
    //@Log(title = "查看用户列表", businessType = BusinessType.SELECT,  isSaveRequestData = false)
    @PostMapping("/getUserList")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<PageResult<List<UserVO>>> getUserList(@RequestBody @Valid GetUserListDTO getUserListDTO) {
        GetUserListDO getUserListDO=EntityConversionUtil.copy(getUserListDTO,GetUserListDO.class);
        getUserListDO.setUserType(UserType.USER.getCode());
        List<SysUser> sysUserList = sysUserService.getUser(getUserListDO);
        PageInfo<SysUser> pageInfo = new PageInfo<>(sysUserList);
        List<UserVO> userVOList = EntityConversionUtil.copyList(sysUserList, UserVO.class);
        PageResult<List<UserVO>> build = PageResult.<List<UserVO>>builder().result(userVOList).pageInfo(pageInfo).build();
        return Result.suc(build);
    }
}
